import card, { cardSet, cardGet } from "@/ts/cardData/card"
import type { colDataOption, colDataOthers, colOthers, spanEunm, col, colOption, colData } from "@/ts/cardType/col"
import { cardScript, cardScriptRun } from "../cardData/cardScript"
type barTypeEunm = 'simple' | 'addable'
export default class bar {
    type: barTypeEunm
    cols: (col | { value: string, span?: spanEunm, others?: colOthers })[]
    /**
     * 卡面的所有相关键
     */
    keys: string[]
    /**
     * @param otherKeys 未出现在cols中的相关的key
     */
    constructor(type: barTypeEunm, cols: (col | { value: string, span?: spanEunm, others?: colOthers })[], otherKeys?: string[]) {
        this.type = type
        this.cols = cols
        let keys: string[] = [...otherKeys ?? []]
        for (const col of cols) {
            if ('key' in col && !keys.includes(col.key)) {
                keys.push(col.key)
            }
        }
        this.keys = keys
    }
}

export function barGetValue(bar: bar, card: card, index: number[]): colData[] {
    let vaules: colData[] = []
    for (const col of bar.cols) {
        if ('value' in col) {
            vaules.push({
                value: col.value,
                span: col.span ?? 12,
                option: {
                    readonly: true
                },
                others: autoGetOther(col.others, card, index)
            })
        } else {
            vaules.push({
                value: col.getVaule != undefined ? cardScriptRun(card, index, col.getVaule)?.toString() : cardGet(card, col.key, index) ?? '',
                span: col.span ?? 12,
                option: autoGetOption(col.option, card, index),
                others: autoGetOther(col.others, card, index)
            })
        }
    }
    return vaules
}
export function barSetValue(bar: bar, targetIndex: number):cardScript|undefined {
    const col = bar.cols[targetIndex]
    if (!('value' in col)) {
       return col.setVaule??{
        member:[col.key,"${value}"],
        relation:'set'
       }
    }
}
export function textBar(name: string, key: string, option?: colOption, getVaule?: cardScript, setVaule?: cardScript): bar {
    return new bar('simple', [{ value: name, span: 6 }, { key: key, option: option, getVaule, setVaule }])
}
export function balanceBar(name: string, key: string,
    max: number | cardScript,
    min: number | cardScript,
    option: {
        placeholder?: string, leftColor?: string, rightColor?: string, hideValue?: boolean, clickable?: boolean
        getVaule?: cardScript,
        setVaule?: cardScript,
    } = {}) {
    let b = new bar('simple', [{
        value: name,
        span: 6
    }, {
        key: key,
        option: {
            type: 'progress'
        },
        span: 18,
        others: {
            max: max,
            min: min,
            colors: [option.leftColor, option.rightColor],
            hideValue: option.hideValue ?? false,
            clickable: option.clickable ?? true
        }
    }])
    return b
}
export function doubleMaxBar(title: string,
    value: { key: string, getValue?: cardScript, setValue?: cardScript },
    max: { key: string, getValue?: cardScript, setValue?: cardScript },
    secondMax: { key: string, getValue?: cardScript, setValue?: cardScript },
    statusKey: string, statusEunm: string[], statusColorEunm: string[]) {
    const colorGetterValue: cardScript = {
        relation: '?:',
        member: []
    }
    let target = colorGetterValue
    for (let i = 0; i < statusEunm.length; i++) {
        const status = statusEunm[i];
        const color = statusColorEunm[i]
        target.member[0] = {
            relation: '==',
            member: [status, {
                relation: 'get',
                member: [statusKey]
            }]
        }
        target.member[1] = color
        target.member[2] = {
            relation: '?:',
            member: []
        }
        if (i == statusEunm.length - 1) { target.member[2] = '#000'; break; }
        target = target.member[2]
    }
    const b = new bar('simple', [{
        value: title, span: 6
    }, {
        ...value, span: 6
    }, {
        ...max, span: 6
    }, {
        ...secondMax, span: 6
    }, {
        key: statusKey, span: 6,
        option: {
            type: 'eunm'
        },
        getVaule: {
            relation: '?:',
            member: [{
                relation: '==',
                member: [{
                    relation: 'get', member: [statusKey]
                }, '']
            }, {
                relation: 'set', member: [statusKey, statusEunm[0]]
            }, {
                relation: 'get', member: [statusKey]
            }]
        },
        others: {
            valueOption: statusEunm,
            colors: statusColorEunm
        }
    }, {
        key: value.key, span: 18,
        option: {
            type: 'double_progress'
        },
        others: {
            max: { relation: 'get', member: [max.key] },
            secondMax: { relation: 'get', member: [secondMax.key] },
            colors: [colorGetterValue, '#00000000', statusColorEunm[1] ?? statusColorEunm[0], '#00000000']
        }
    }
    ])
    return b
}
export function maxBar(title: string,
    value: { key: string, getValue?: cardScript, setValue?: cardScript },
    max: { key: string, getValue?: cardScript, setValue?: cardScript },
    statusKey: string, statusEunm: string[], statusColorEunm: string[]) {
    const colorGetterValue: cardScript = {
        relation: '?:',
        member: []
    }
    let target = colorGetterValue
    for (let i = 0; i < statusEunm.length; i++) {
        const status = statusEunm[i];
        const color = statusColorEunm[i]
        target.member[0] = {
            relation: '==',
            member: [status, {
                relation: 'get',
                member: [statusKey]
            }]
        }
        target.member[1] = color
        target.member[2] = {
            relation: '?:',
            member: []
        }
        if (i == statusEunm.length - 1) { target.member[2] = '#000'; break; }
        target = target.member[2]
    }
    const b = new bar('simple', [{
        value: title, span: 8
    }, {
        ...value, span: 8
    }, {
        ...max, span: 8
    }, {
        key: statusKey, span: 8,
        option: {
            type: 'eunm'
        },
        getVaule: {
            relation: '?:',
            member: [{
                relation: '==',
                member: [{
                    relation: 'get', member: [statusKey]
                }, '']
            }, {
                relation: 'set', member: [statusKey, statusEunm[0],]
            }, {
                relation: 'get', member: [statusKey]
            }]
        },
        others: {
            valueOption: statusEunm,
            colors: statusColorEunm
        }
    }, {
        key: value.key, span: 16,
        option: {
            type: 'progress'
        },
        others: {
            max: { relation: 'get', member: [max.key] },
            colors: [colorGetterValue, '#00000000'],
            hideValue: true
        }
    }
    ])
    return b
}
function autoGetOption(option: colOption | undefined, card: card, index: number[]): colDataOption {
    if (option == undefined) return {}
    return {
        //@ts-expect-error
        type: (typeof option.type == 'object') ? cardScriptRun(card, index, option.type) : option.type,
        //@ts-expect-error
        readonly: (typeof option.readonly == 'object') ? cardScriptRun(card, index, option.readonly) : option.readonly,
        //@ts-expect-error
        placeholder: (typeof option.placeholder == 'object') ? cardScriptRun(card, index, option.placeholder) : option.placeholder
    }
}
function autoGetOther(others: colOthers | undefined, card: card, index: number[]): colDataOthers {
    if (others == undefined) return {}
    return {
        //@ts-expect-error
        max: (typeof others.max == 'object') ? cardScriptRun(card, index, others.max) : others.max,
        //@ts-expect-error
        secondMax: (typeof others.secondMax == 'object') ? cardScriptRun(card, index, others.secondMax) : others.secondMax,
        //@ts-expect-error
        min: (typeof others.min == 'object') ? cardScriptRun(card, index, others.min) : others.min,
        //@ts-expect-error
        colors: others.colors?.flatMap(ele => (typeof ele == 'object') ? cardScriptRun(card, index, ele) : ele),
        //@ts-expect-error
        clickable: (typeof others.clickable == 'object') ? cardScriptRun(card, index, others.clickable) : others.clickable,
        //@ts-expect-error
        hideValue: (typeof others.hideValue == 'object') ? cardScriptRun(card, index, others.hideValue) : others.hideValue,
        //@ts-expect-error
        valueOption: others.valueOption?.flatMap(ele => (typeof ele == 'object') ? cardScriptRun(card, index, ele) : ele),
        //@ts-expect-error
        lines: (typeof others.lines == 'object') ? cardScriptRun(card, index, others.lines) : others.lines
    }

}
